package com.maixy.studyonlineapi.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.maixy.studyonlineapi.bean.SessionUser;
import com.maixy.studyonlineapi.entity.Media;
import com.maixy.studyonlineapi.entity.Team;
import com.maixy.studyonlineapi.entity.User;
import com.maixy.studyonlineapi.enums.MediaTypeEnum;
import com.maixy.studyonlineapi.exceptions.TipException;
import com.maixy.studyonlineapi.mapper.UserMapper;
import com.maixy.studyonlineapi.utils.DataTypeUtil;
import com.maixy.studyonlineapi.utils.JwtUtils;
import com.maixy.studyonlineapi.utils.OssUtil;
import com.maixy.studyonlineapi.view.MediaView;
import com.maixy.studyonlineapi.view.UserBasisInfoView;
import com.maixy.studyonlineapi.view.UserView;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * @Classname UserService
 * @Description TODO
 * @Date 2020/11/1 16:51
 * @Author by maixy
 */
@Service
@Slf4j
public class UserService extends BaseMPlusService<User, Long>{
    private final UserMapper userMapper;

    @Resource
    private MediaService mediaService;
    @Resource
    private TeamService teamService;
    @Resource
    private TeamUserService teamUserService;
    @Resource
    private AuthService authService;
    @Resource
    private ActivityService activityService;
    @Resource
    private OssUtil ossUtil;

    protected UserService(UserMapper userMapper) {
        super(User.class, userMapper);
        this.userMapper = userMapper;
    }

    /**
     * 生成一个新的用户
     * @param userName 用户名
     * @param pwd 密码
     * @param nickName 用户昵称
     * @param avatarUrl 用户头像url
     * @return com.maixy.studyonlineapi.entity.User
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public User create(String userName,String pwd,String nickName,String avatarUrl) {
        if (null != findUserByUserName(userName)) {
            throw new TipException("用户名已被占用");
        }
        if (ossUtil.exist(avatarUrl)) {
            MediaView mediaView = mediaService.saveMedia(MediaTypeEnum.IMAGE.getCode(), avatarUrl);
            User user = new User();
            user.setUserName(userName);
            user.setPwd(pwd);
            user.setNickName(nickName);
            user.setAvatarId(DataTypeUtil.getLong(mediaView.getMediaId(), -1L));
            user.setHasDelete(false);
            user = create(user);
            return user;
        } else {
            throw new TipException("文件不存在");
        }

    }

    /**
     * 生成用户Session
     * @param user 用户id
     * @return com.maixy.studyonlineapi.bean.SessionUser
     */
    public SessionUser buildUserInfo(User user) {
        if (null == user || user.getHasDelete()) {
            throw new TipException("用户不存在或已被删除");
        }
        SessionUser sessionUser = new SessionUser();
        Media media = mediaService.findById(user.getAvatarId());
        if (null == media || media.getHasDelete()) {
            throw new TipException("找不到头像信息");
        }
        String sessionId = JwtUtils.createToken(user.getId(), user.getUserName(), user.getNickName(), media.getMediaUrl());
        sessionUser.setSessionId(sessionId);
        sessionUser.setUserId(String.valueOf(user.getId()));
        sessionUser.setUserName(user.getUserName());
        sessionUser.setNickName(user.getNickName());
        sessionUser.setAvatarUrl(media.getMediaUrl());
        return sessionUser;
    }


    /**
     * 根据用户名查询用户
     * @param userName 用户名
     * @return com.maixy.studyonlineapi.entity.User
     */
    public User findUserByUserName(String userName) {
        return userMapper.selectOne(new QueryWrapper<User>()
                .lambda()
                .eq(User::getUserName, userName)
                .eq(User::getHasDelete, false)
                .orderByDesc(User::getCreateTime)
                .last("limit 1"));
    }

    /**
     * 根据用户名和密码查询用户
     * @param userName 用户名
     * @param pwd 密码
     * @return com.maixy.studyonlineapi.entity.User
     */
    public User findUserByUserNameAndPwd(String userName, String pwd) {
        return userMapper.selectOne(new QueryWrapper<User>()
                .lambda()
                .eq(User::getUserName, userName)
                .eq(User::getPwd, pwd)
                .eq(User::getHasDelete, false)
                .orderByDesc(User::getCreateTime)
                .last("limit 1"));
    }

    /**
     * 用户id，昵称，头像视图
     *
     * @param user 用户实体类
     * @return com.maixy.studyonlineapi.view.UserView
     */
    public UserView convert(User user) {
        UserView view = new UserView();
        view.setUserId(DataTypeUtil.getStr(user.getId()));
        view.setNickName(user.getNickName());
        Media media = mediaService.findById(user.getAvatarId());
        if (null == media || media.getHasDelete()) {
            throw new TipException("找不到头像信息");
        }
        view.setAvatarUrl(media.getMediaUrl());
        return view;
    }

    /**
     * 用户基本信息
     *
     * @param teamId 团队id
     * @param userId 用户id
     */
    public UserBasisInfoView getUserBasisInfo(Long teamId, Long userId) {
        if (!teamService.hasPower(teamId, userId)) {
            throw new TipException("没有权限！");
        }
        UserBasisInfoView view = new UserBasisInfoView();
        view.setHasTeamCreateBy(teamService.isSuperManager(teamId, userId));
        Team team = teamService.findById(teamId);
        if (null == team || team.getHasDelete()) {
            throw new TipException("团队不存在或已被删除");
        }
        User user = findById(team.getCreateBy());
        if (null == user || user.getHasDelete()) {
            throw new TipException("用户不存在或已被删除");
        }
        view.setTeamCreateByName(user.getNickName());
        view.setTeamUserCount(teamUserService.countTeamUser(teamId));
        view.setActivityNum(activityService.countActivity(team.getCreateBy()));
        view.setJoinActivityNum(authService.countAuthNum(userId));
        return view;
    }

    public SessionUser updateNickName(Long userId, String nickName) {
        User user = findById(userId);
        if (null == user || user.getHasDelete()) {
            throw new TipException("用户不存在或已被删除");
        }
        user.setNickName(nickName);
        user.setUpdateBy(userId);
        user.setUpdateTime(System.currentTimeMillis());
        update(user);
        return buildUserInfo(user);
    }

    public SessionUser updateAvatarUrl(Long userId, String avatarUrl) {
        User user = findById(userId);
        if (null == user || user.getHasDelete()) {
            throw new TipException("用户不存在或已被删除");
        }

        if (ossUtil.exist(avatarUrl)) {
            MediaView mediaView = mediaService.saveMedia(MediaTypeEnum.IMAGE.getCode(), avatarUrl);
            user.setAvatarId(DataTypeUtil.getLong(mediaView.getMediaId(), -1L));
            user.setUpdateBy(userId);
            user.setUpdateTime(System.currentTimeMillis());
            update(user);
        } else {
            throw new TipException("文件不存在");
        }

        return buildUserInfo(user);
    }

    public void updatePwd(String oldPwd, String pwd, String confirmPwd, Long userId) {
        User user = findById(userId);
        if (null == user || user.getHasDelete()) {
            throw new TipException("用户不存在或已被删除");
        }
        if (!user.getPwd().equals(oldPwd)) {
            throw new TipException("密码不正确");
        }

        if (!pwd.equals(confirmPwd)) {
            throw new TipException("两次密码输入不一致");
        }

        user.setPwd(pwd);
        user.setUpdateTime(System.currentTimeMillis());
        user.setUpdateBy(userId);
        update(user);
    }
}
